package com.tuniu.agents.tools.flights.domestic.oneway;

import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.tuniu.agents.advisor.ChatEnvironmentMemory;
import com.tuniu.agents.message.MessageSender;
import com.tuniu.agents.message.ToolLogger;
import com.tuniu.agents.message.ToolLoggerInfo;
import com.tuniu.agents.tools.flights.FlightProperties;
import com.tuniu.agents.tools.flights.enums.FlightToolEnum;
import com.tuniu.agents.tools.flights.utils.AirportQueryUtils;
import com.tuniu.agents.tools.flights.utils.FlightMessageUtils;
import com.tuniu.agents.util.HttpManager;
import com.tuniu.agents.util.I18nUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;

public class FlightTransferQueryTool implements BiFunction<FlightTransferQueryTool.Request, ToolContext, FlightLowPriceQueryTool.Response>, ToolLogger {

    public static final String TOOLNAME = "FlightTransferQueryTool";

    private static final Logger logger = LoggerFactory.getLogger(FlightTransferQueryTool.class);

    private final String flightTransferQueryToolUrl;
    private final String flightNearGoQueryToolUrl;
    private final String flightNearBackQueryToolUrl;

    private final String approachUrl;

    @Autowired
    private HttpManager httpManager;

    @Autowired(required = false)
    private ChatEnvironmentMemory chatEnvironmentMemory;

    @Autowired
    private MessageSender messageSender;

    public FlightTransferQueryTool(FlightProperties properties) {
        this.flightTransferQueryToolUrl = properties.getFlightTransferQueryToolUrl();
        this.flightNearGoQueryToolUrl = properties.getFlightNearGoQueryToolUrl();
        this.flightNearBackQueryToolUrl = properties.getFlightNearBackQueryToolUrl();
        this.approachUrl = properties.getApproachQueryToolUrl();
    }

    @ToolLoggerInfo(beanName = TOOLNAME)
    @Override
    public FlightLowPriceQueryTool.Response apply(Request request, ToolContext context) {
        try {
            // Get the custom parameters corresponding to the session
            Map<String, Object> map = context.getContext();
            String conversationId = (String) map.get("conversation_id");
            logger.info("FlightTransferQueryTool request parameters: {}", request);
            FlightLowPriceQueryTool.Response post;
            List<String> cityList = new ArrayList<>();
            cityList.add(request.departureCityName);
            cityList.add(request.arrivalCityName);
            Map<String, Boolean> mapCity = AirportQueryUtils.batchCheckAirports(httpManager, approachUrl, cityList);
            String[] loadingStr = FlightToolEnum.FLIGHT_TRANSFER_LIST.getInner().split(",");
            if (mapCity.get(request.departureCityName)) {
                messageSender.send((String) map.get("conversation_id"), I18nUtil.getMessage(conversationId,loadingStr[0]));
                post = httpManager.post(flightNearGoQueryToolUrl, request, FlightLowPriceQueryTool.Response.class);
                logger.info("flightApiUrl: {}", flightNearGoQueryToolUrl);
            } else if (mapCity.get(request.arrivalCityName)) {
                messageSender.send((String) map.get("conversation_id"), I18nUtil.getMessage(conversationId,loadingStr[1]));
                post = httpManager.post(flightNearBackQueryToolUrl, request, FlightLowPriceQueryTool.Response.class);
                logger.info("flightApiUrl: {}", flightNearBackQueryToolUrl);
            } else {
                post = httpManager.post(flightTransferQueryToolUrl, request, FlightLowPriceQueryTool.Response.class);
                logger.info("flightApiUrl: {}", flightTransferQueryToolUrl);
            }
            if (post.queryId() != null) {
                Map<String, Object> hashMap = chatEnvironmentMemory.get((String) map.get("conversation_id"));
                hashMap.put("queryId", post.queryId());
                hashMap.put("departureCityName", request.departureCityName);
                hashMap.put("arrivalCityName", request.arrivalCityName);
                hashMap.put("departureDate", request.departureDate);
                hashMap.put("backDepartureDate", "");
                chatEnvironmentMemory.add((String) map.get("conversation_id"), hashMap);
            }
            return post.buildResponse();
        } catch (Exception e) {
            logger.error("FlightTransferQueryTool request exception: {}", e.getMessage());
            return null;
        }
    }

    @Override
    public List<String> before(Object request, ToolContext context) {
        String conversationId = (String) context.getContext().get("conversation_id");
        Request rRequest = (Request) request;
        if (StringUtils.hasText(rRequest.departureCityName) && StringUtils.hasText(rRequest.arrivalCityName) && StringUtils.hasText(rRequest.departureDate)) {
            return List.of(FlightMessageUtils.getShowMessage(rRequest.departureCityName, rRequest.arrivalCityName, rRequest.departureDate, null,conversationId),
                    I18nUtil.getMessage(conversationId, FlightToolEnum.FLIGHT_TRANSFER_LIST.getBefore()));
        }
        return null;
    }

    @Override
    public List<String> after(Object request, ToolContext context, Object response) {
        FlightLowPriceQueryTool.Response result = (FlightLowPriceQueryTool.Response) response;
        String conversationId = (String) context.getContext().get("conversation_id");
        if (response != null && result.data() != null) {
            return List.of(FlightMessageUtils.getToolMessage(result.data().size(), conversationId));
        }
        return null;
    }

    @JsonClassDescription("国内机票中转最快航班查询入参")
    public record Request(
            @JsonProperty(required = true,
                    value = "departureCityName") @JsonPropertyDescription("出发城市") String departureCityName,
            @JsonProperty(required = true,
                    value = "arrivalCityName") @JsonPropertyDescription("到达城市") String arrivalCityName,
            @JsonProperty(required = true,
                    value = "departureDate") @JsonPropertyDescription("出发日期,格式:yyyy-MM-dd") String departureDate) {
    }
}